#include "rudp.h"
#include <stdio.h>
#include <stdlib.h>  
#include <stdint.h>
#include <unistd.h>  
#include <string.h>  
#include <pthread.h>  
#include <netinet/in.h>  
#include <errno.h>  
#include <fcntl.h>

#include <sys/time.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
#include <sys/select.h>  


static void
dump_recv(struct rudp *U) {
	char tmp[MAX_PACKAGE];
	int n;
	while ((n = rudp_recv(U, tmp))) {
		if (n < 0) {
			//printf("CORRPUT\n");
			break;
		}
		int i;
		printf("RECV ");
		for (i=0;i<n;i++) {
			printf("%02x ", (uint8_t)tmp[i]);
		}
		printf("\n");
	}
}

static void
pack_send(struct rudp_package *p, int sock, struct sockaddr * addr) {
	static int idx = 0;
	printf("%d : ", idx++);
	while (p) {
		printf("(");

		int i;
		for (i=0;i<p->sz;i++) {
			printf("%02x ", (uint8_t)p->buffer[i]);
		}

		if (idx >10 && idx < 15){
			printf("drop %d",idx);
		}
		else{
			sendto(sock, p->buffer, p->sz,0, addr, sizeof(*addr));  
		}

		printf(") ");
		p=p->next;
	}
	printf("\n");
}

static void udp_noblock(int sock)
{
	int flags = 0;
	flags = fcntl(sock, F_GETFL, 0); 
	fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

static int udp_select(int sock, int timeoutsec)
{
	struct timeval timeout;    // 定时变量
	fd_set rset;//创建文件描述符的聚合变量
	int ret = 0;  
    FD_ZERO(&rset);  
    FD_SET(sock, &rset);  

    timeout.tv_sec = timeoutsec;   
    timeout.tv_usec = 0;  

    ret = select(sock + 1, &rset, NULL, NULL, &timeout);
    if (ret == 0){
    	return 0;
    }

    if (ret > 0){
    	if (FD_ISSET(sock, &rset)){
    		return 1;
    	}
    }
    return -1;
}

static int
update_send_and_recv(struct rudp *U, int sock,int tick, struct sockaddr* send_addr) {
	char message[512];
	int ret = 0;
	int select_ret = 0;
	struct rudp_package *send = NULL;
    struct sockaddr addr;
    int    addr_len = sizeof(addr);

	select_ret  = udp_select(sock, 1);
    
    printf("select ret %d\n", ret);

	if (select_ret > 0){

		ret  = recvfrom(sock, message, sizeof(message), 0, &addr, (socklen_t *)&addr_len);  

		printf("recv ret %d \n", ret);

		if (ret > 0){
			send = rudp_update(U, message, ret, tick);
		}

	}else{
		send = rudp_update(U, NULL, 0, tick);
	}

	if (send)
		pack_send(send, sock, send_addr);
	return select_ret;
}


int port=6770;  

int main(int argc, char** argv) {  
    int socket_descriptor; //套接口描述字  
    int iter=0; 
    int ret = 0; 
    char buf[512];  
    struct sockaddr_in address;//处理网络通信的地址  

    struct rudp *U = rudp_new(1, 5);

    bzero(&address,sizeof(address));  
    address.sin_family=AF_INET;  
    //address.sin_addr.s_addr=inet_addr("119.23.148.24");//这里不一样  
    address.sin_addr.s_addr=inet_addr("127.0.0.1");//这里不一样  
    address.sin_port=htons(port); 
  	
    //创建一个 UDP socket  
  
    socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4  SOCK_DGRAM 数据报套接字（UDP协议）  
  
    udp_noblock(socket_descriptor);

    while(1)  
    {  
    	iter++;
        sprintf(buf,"123456789 %d\n",iter); 
         
        rudp_send(U, buf, strlen(buf));

		ret = update_send_and_recv(U, socket_descriptor,  1, (struct sockaddr*)&address);

		dump_recv(U);

		if ( ret != 0 ){
			sleep(1);
		}

		printf("%d \n", iter);
    }  
  

   	rudp_delete(U);

    close(socket_descriptor);  
    printf("Messages Sent,terminating\n");  
  
    exit(0);  
  
    return (EXIT_SUCCESS);  
}  
